﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using Utilities;
using StockCommon.data;

namespace StockCommon
{
    public class StockCodeManager
    {
        public class StockIndexItem
        {
            public Guid id ;
            public String 個股 { get; set; }
            public String 代號 { get; set; }
            public String 名稱;
            public String 市場 { get; set; }
            public String 類別 { get; set; }
            public DateTime? 最後資料日期;
            public decimal? 最新股本;
            public long? 發行量;
        }

        protected static StockCodeManager instance = new StockCodeManager();

        protected static Dictionary<string, StockIndexItem> stockCodes;

        protected StockCodeManager()
        {
            initStockCodes();
        }
        protected static HashSet<String> codes_tse = null;
        protected static HashSet<String> codes_otc = null;
        public static HashSet<String> getStockCodes(TwnStockMarketType t)
        {
            switch (t)
            {
                case TwnStockMarketType.上櫃:
                    if (codes_otc == null)
                        codes_otc = getStockCodes_internal(TwnStockMarketType.上櫃);
                    return codes_otc;
                case TwnStockMarketType.上市:
                    if (codes_tse == null)
                        codes_tse = getStockCodes_internal(TwnStockMarketType.上市);
                    return codes_tse;
            }
            return null;
        }
        protected  static HashSet<String> getStockCodes_internal(TwnStockMarketType t)
        {
            HashSet<String> result=new HashSet<string>();
            String market=EnumUtils.GetStringValue(t);
            foreach(StockIndexItem item in stockCodes.Values)
            {
                if (market.Equals(item.市場))
                    result.Add(item.代號);
            }
            return result;
        }
        public static HashSet<String> filterForMarket(List<String> codes, TwnStockMarketType t)
        {
            String m="tse";
            if(TwnStockMarketType.上櫃.Equals(t))
                m="otc";
            HashSet<String> result = new HashSet<String>();
            foreach (String code in codes)
            {
                if (m.Equals(stockCodes[code].市場))
                    result.Add(code);
            }
            return result;
        }

        public static StockDataClassesDataContext getContext()
        {
            return LinqAgent.getContext();
        }
        private static void initStockCodes()
        {
            if (stockCodes != null)
                return;
            StockDataClassesDataContext context = LinqAgent.getContext();
            stockCodes = context.ExecuteQuery<StockIndexItem>("select 代號+' '+名稱  as 個股,* from stockIndex").ToDictionary(x => x.代號);
        }
        protected void addDataToStockCodes(String code)
        {
            StockDataClassesDataContext context = LinqAgent.getContext();
            StockIndexItem si=context.ExecuteQuery<StockIndexItem>("select 代號+' '+名稱  as 個股,* from stockIndex where 代號='" + code + "'").FirstOrDefault();
            if(si!=null)
            stockCodes.Add(si.代號, si);
        }
        public static List<StockIndexItem> getLatestStockCodeList()
        {
            StockDataClassesDataContext context = getContext();
            DateTime dt=DateTime.Now.AddMonths(-1); //取得一個月內的
            String ds=DateUtils.toShortDateFormat(dt);
            String pat = "select  代號+' '+名稱  as 個股,* from StockIndex where 代號 in "+
                                  "(select distinct 證券代號 as stockCode from StockDaily where StockDaily.日期 > '{0}')  order by  市場 desc, 代號";
            String sql=String.Format(pat,ds);
            List<StockIndexItem> stocks = context.ExecuteQuery<StockIndexItem>(sql).ToList();
            return stocks;
        }
        
        public static String getStockName(String code)
        {
            code=code.Trim();
            if (stockCodes.ContainsKey(code))
            {
                return stockCodes[code].名稱;
            }
            return null;
        }
        public static List<String> getStockCodeLike(String like)
        {
            StockCommon.StockDataClassesDataContext context = StockCommon.LinqAgent.getContext();

            String opt = "";
            if (String.IsNullOrEmpty(like) == false)
            {
                opt = String.Format(" 代號 like '%{0}%' or 名稱 like '%{0}%') and ", like);
            }
            String sql = "select 代號+' '+名稱  as codeName from StockIndex where " + opt + " LEN([代號])<=4 order by 市場,代號";
            List<String> result = context.ExecuteQuery<String>(sql).ToList<String>();
            return result;
        }
        protected static bool updateStockCategory_internal(String code, String catName, Guid catId, String 市場)
        {
            StockDataClassesDataContext context = getContext();
            StockIndex si = (from c in context.StockIndexes where c.代號 == code select c).FirstOrDefault<StockIndex>();
            if (si == null)
                return false;
            if (catId.Equals(si.catId))
                return true;
            si.catId = catId;
            si.市場 = 市場;
            si.類別 = catName;
            si.國家 = "tw";
            context.SubmitChanges();
            return true;
        }
        public static bool updateOtcStockCategory(String code, String catName, Guid catId)
        {
            return updateStockCategory_internal(code, catName, catId, "otc");
        }

        public static bool updateTseStockCategory(String code, String catName, Guid catId)
        {
            return updateStockCategory_internal(code, catName, catId, "tse");
        }
        protected static Guid updateBasicCategory(string catName, string catCode, int seq, String market)
        {
            StockCategory cc = (from c in getContext().StockCategories where (c.market == market && c.catId == catCode) select c).FirstOrDefault<StockCategory>();
            if (cc != null)
                return cc.id;
            cc = new StockCategory();
            cc.id = NewGuid.create("cate");
            cc.catgoryName = catName;
            cc.isBasic = true;
            cc.seq = seq;
            cc.market = market;
            cc.catId = catCode;
            StockDataClassesDataContext context = getContext();
            context.StockCategories.InsertOnSubmit(cc);
            context.SubmitChanges();
            return cc.id;
        }
        public static Guid UpdateOtcBasicCategory(string catName, string catCode, int seq)
        {
            return updateBasicCategory(catName, catCode, seq, "otc");
        }
        public static Guid UpdateTseBasicCategory(String catName, String catCode, int seq)
        {
            return updateBasicCategory(catName, catCode, seq, "tse");
        }
        public static void updateToMarket(String code, String market)
        {
            String pat = "update stockIndex set 市場='{0}' where  代號='{1}' ";
            String ss = string.Format(pat, market, code);
            int c=getContext().ExecuteCommand(ss);
        }
        public static Guid getTseId(String code)
        {
            code = code.Trim();
            if (stockCodes.ContainsKey(code))
            {
                if ("tse".Equals(stockCodes[code].市場) == false)
                {
                    updateToMarket(code, "tse");
                    stockCodes[code].市場 = "tse";
                }
                return stockCodes[code].id;
            }
            return Guid.Empty;
        }
        public static Guid getGreTaiId(String code)
        {
            code=code.Trim();
            if (stockCodes.ContainsKey(code))
            {
                if ("otc".Equals(stockCodes[code].市場) == false)
                {
                    updateToMarket(code, "otc");
                    stockCodes[code].市場 = "otc";
                }
                return stockCodes[code].id;
            }
            return Guid.Empty;
        }
        /***********************************************************************************
         * 
         * 
         * **********************************************************************************/
        public static Guid createStock(String code, String name, String  market,DateTime d, int 發行量 = 0)
        {
            if (stockCodes.ContainsKey(code))
                return stockCodes[code].id;

            StockIndex si = new StockIndex();
            si.id = NewGuid.create("stck");
            si.代號 = code;
            si.市場 = market;
            si.名稱 = name;
            if (發行量 != 0)
                si.發行量 = 發行量;
            si.是否有效 = true;
            si.最後資料日期 = DateUtils.getDateOnly(d);
            getContext().StockIndexes.InsertOnSubmit(si);
            getContext().SubmitChanges();
            
            return si.id;
        }
        
    }
}
